home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
- /* zap.c - version 1.0.3 */
-
- #include "hack.h"
-
- extern struct obj *mkobj_at();
- extern struct monst *makemon(), *mkmon_at(), youmonst;
- extern struct monst *bhit();
- extern char *exclam();
-
- extern char *fl[];
-
- /* type == -1: monster spitting fire at you */
- /* type == -1,-2,-3: bolts sent out by wizard */
- /* called with dx = dy = 0 with vertical bolts */
- buzz(type,sx,sy,dx,dy)
- register int type;
- register xchar sx,sy;
- register int dx,dy;
- {
- int abstype = abs(type);
- register char *fltxt = (type == -1) ? "blaze of fire" : fl[abstype];
- struct rm *lev;
- xchar range;
- struct monst *mon;
-
- if(u.uswallow) {
- register int tmp;
-
- if(type < 0) return;
- tmp = zhit(u.ustuck, type);
- pline("The %s rips into %s%s",
- fltxt, mon_nam(u.ustuck), exclam(tmp));
- return;
- }
- if(type < 0) pru();
- range = rn1(7,7);
- Tmp_at2(-1, dirlet(dx,dy)); /* open call */
- while(range-- > 0) {
- sx += dx;
- sy += dy;
- if((lev = &levl[sx][sy])->typ) Tmp_at2(sx,sy);
- else {
- int bounce = 0;
- if(cansee(sx-dx,sy-dy))
- pline("The %s bounces!", fltxt);
- if(ZAP_POS(levl[sx][sy-dy].typ))
- bounce = 1;
- if(ZAP_POS(levl[sx-dx][sy].typ)) {
- if(!bounce || rn2(2)) bounce = 2;
- }
- switch(bounce){
- case 0:
- dx = -dx;
- dy = -dy;
- continue;
- case 1:
- dy = -dy;
- sx -= dx;
- break;
- case 2:
- dx = -dx;
- sy -= dy;
- break;
- }
- Tmp_at2(-2,dirlet(dx,dy));
- continue;
- }
- if(lev->typ == POOL && abstype == 1 /* fire */) {
- range -= 3;
- lev->typ = ROOM;
- if(cansee(sx,sy)) {
- mnewsym(sx,sy);
- pline("The water evaporates.");
- } else
- pline("You hear a hissing sound.");
- }
- if((mon = m_at(sx,sy)) &&
- (type != -1 || mon->data->mlet != 'D')) {
- wakeup(mon);
- if(rnd(20) < 18 + mon->data->ac) {
- register int tmp = zhit(mon,abstype);
- if(mon->mhp < 1) {
- if(type < 0) {
- if(cansee(mon->mx,mon->my))
- pline("%s is killed by the %s!",
- Monnam(mon), fltxt);
- mondied(mon);
- } else
- killed(mon);
- } else
- hit(fltxt, mon, exclam(tmp));
- range -= 2;
- } else
- miss(fltxt,mon);
- } else if(sx == u.ux && sy == u.uy) {
- nomul(0);
- if(rnd(20) < 18+u.uac) {
- register int dam = 0;
- range -= 2;
- pline("The %s hits you!",fltxt);
- switch(abstype) {
- case 0:
- dam = d(2,6);
- break;
- case 1:
- if(Fire_resistance)
- pline("You don't feel hot!");
- else dam = d(6,6);
- if(!rn2(3))
- burn_scrolls();
- break;
- case 2:
- nomul(-rnd(25)); /* sleep ray */
- break;
- case 3:
- if(Cold_resistance)
- pline("You don't feel cold!");
- else dam = d(6,6);
- break;
- case 4:
- u.uhp = -1;
- }
- losehp(dam,fltxt);
- } else pline("The %s whizzes by you!",fltxt);
- stop_occupation();
- }
- if(!ZAP_POS(lev->typ)) {
- int bounce = 0, rmn;
- if(cansee(sx,sy)) pline("The %s bounces!",fltxt);
- range--;
- if(!dx || !dy || !rn2(20)){
- dx = -dx;
- dy = -dy;
- } else {
- if(ZAP_POS(rmn = levl[sx][sy-dy].typ) &&
- (IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ)))
- bounce = 1;
- if(ZAP_POS(rmn = levl[sx-dx][sy].typ) &&
- (IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ)))
- if(!bounce || rn2(2))
- bounce = 2;
-
- switch(bounce){
- case 0:
- dy = -dy;
- dx = -dx;
- break;
- case 1:
- dy = -dy;
- break;
- case 2:
- dx = -dx;
- break;
- }
- Tmp_at2(-2, dirlet(dx,dy));
- }
- }
- }
- Tmp_at2(-1,-1);
- }
-
- zhit(mon,type) /* returns damage to mon */
- register struct monst *mon;
- register type;
- {
- register int tmp = 0;
-
- switch(type) {
- case 0: /* magic missile */
- tmp = d(2,6);
- break;
- case -1: /* Dragon blazing fire */
- case 1: /* fire */
- if(index("Dg", mon->data->mlet)) break;
- tmp = d(6,6);
- if(index("YF", mon->data->mlet)) tmp += 7;
- break;
- case 2: /* sleep*/
- mon->mfroz = 1;
- break;
- case 3: /* cold */
- if(index("YFgf", mon->data->mlet)) break;
- tmp = d(6,6);
- if(mon->data->mlet == 'D') tmp += 7;
- break;
- case 4: /* death*/
- if(index(UNDEAD, mon->data->mlet)) break;
- tmp = mon->mhp+1;
- break;
- }
- mon->mhp -= tmp;
- return(tmp);
- }
-
- #define CORPSE_I_TO_C(otyp) (char) ((otyp >= DEAD_ACID_BLOB)\
- ? 'a' + (otyp - DEAD_ACID_BLOB)\
- : '@' + (otyp - DEAD_HUMAN))
- revive(obj)
- register struct obj *obj;
- {
- register struct monst *mtmp;
-
- if(obj->olet == FOOD_SYM && obj->otyp > CORPSE) {
- /* do not (yet) revive shopkeepers */
- /* Note: this might conceivably produce two monsters
- at the same position - strange, but harmless */
- mtmp = mkmon_at(CORPSE_I_TO_C(obj->otyp),obj->ox,obj->oy);
- delobj(obj);
- }
- return(!!mtmp); /* TRUE if some monster created */
- }
-
- rloco(obj)
- register struct obj *obj;
- {
- register tx,ty,otx,oty;
-
- otx = obj->ox;
- oty = obj->oy;
- do {
- tx = rn1(COLNO-3,2);
- ty = rn2(ROWNO);
- } while(!goodpos(tx,ty));
- obj->ox = tx;
- obj->oy = ty;
- if(cansee(otx,oty))
- newsym(otx,oty);
- }
-
- fracture_rock(obj) /* fractured by pick-axe or wand of striking */
- register struct obj *obj; /* no texts here! */
- {
- /* unpobj(obj); */
- obj->otyp = ROCK;
- obj->quan = 7 + rn2(60);
- obj->owt = weight(obj);
- obj->olet = WEAPON_SYM;
- if(cansee(obj->ox,obj->oy))
- prl(obj->ox,obj->oy);
- }
-
- burn_scrolls()
- {
- register struct obj *obj, *obj2;
- register int cnt = 0;
-
- for(obj = invent; obj; obj = obj2) {
- obj2 = obj->nobj;
- if(obj->olet == SCROLL_SYM) {
- cnt++;
- useup(obj);
- }
- }
- if(cnt > 1) {
- pline("Your scrolls catch fire!");
- losehp(cnt, "burning scrolls");
- } else if(cnt) {
- pline("Your scroll catches fire!");
- losehp(1, "burning scroll");
- }
- }
-